/* 
 * File:   SimplexTC.h
 * Author: bastian
 *
 * Created on 31 de mayo de 2011, 20:45
 */


#ifndef MATH_H
#include <math.h>
#define MATH_H
#endif

#ifndef FRACCIONES_H
#include "Fracciones.h"
#define FRACCIONES_H
#endif

#ifndef MATRICES_H
#include "Matrices.h"
#define MATRICES_H
#endif

#ifndef TABLASIMPLEX_H
#include "TablaSimplex.h"
#define TABLASIMPLEX_H
#endif


//Definicion de Funciones
void TC_Iteracion(TablaSimplex *tabla, int tipo);
Fraccion TC_NuevoElemento(Matriz *m,int i, int j, int FilP, int ColP);
Fraccion TC_NuevoElementoFilP(Matriz *m,int i, int j, int FilP, int ColP);
Fraccion TC_NuevoElementoColP(Matriz *m,int i, int j, int FilP, int ColP);
Fraccion TC_NuevoPivote(Matriz *m,int FilP, int ColP);


//------------------------------------------------------------------------------

void TC_Iteracion(TablaSimplex *tabla, int tipo){
    
    Matriz *temporal = Matriz_new(tabla->Filas,tabla->Columnas);
    Fraccion Cero,Uno;
    int FilP;
    int ColP;
    
    if(tipo == 1){
        FilP= tabla->FilaPivotePrimal;
        ColP = tabla->ColumnaPivotePrimal;
    }
    
    else if(tipo == 2){
        FilP= tabla->FilaPivoteDual;
        ColP = tabla->ColumnaPivoteDual;
    }
    
    Fraccion_setValue(&Cero,0,1);
    Fraccion_setValue(&Uno,1,1);
    
    for(int i = 0; i < tabla->Filas; i++){
        for(int j = 0; j <tabla->Columnas; j++){
            temporal->elementos[i][j]=tabla->MatrizAsociada->elementos[i][j];
        }
        
    }
    
    
    for(int i = 0; i < tabla->Filas; i++){
        for(int j = 0; j <tabla->Columnas; j++){
            
            if(i!=FilP && j!=ColP)
                tabla->MatrizAsociada->elementos[i][j]=TC_NuevoElemento(temporal,i,j,FilP,ColP);
            
            else if(j==ColP && i!=FilP)
                tabla->MatrizAsociada->elementos[i][j]=TC_NuevoElementoColP(temporal,i,j,FilP,ColP);
            
            else if (i==FilP && j!=ColP)
                tabla->MatrizAsociada->elementos[i][j]=TC_NuevoElementoFilP(temporal,i,j,FilP,ColP);
            
            else if(i==FilP && j==ColP)
                tabla->MatrizAsociada->elementos[i][j]=TC_NuevoPivote(temporal,i,j); 
        }
    }
    
   
   
    TablaSimplex_Matriz_a_Tabla(tabla,tabla->MatrizAsociada);
    //free's
    free(temporal);
}

Fraccion TC_NuevoElemento(Matriz *m,int i, int j, int FilP, int ColP){
    
    Fraccion Mul,Div,NuevoValor,ValorAntiguo;
    Fraccion Pivote = m->elementos[FilP][ColP];
    
    ValorAntiguo = m->elementos[i][j];
    Mul = Fraccion_Multiplicar(&m->elementos[i][ColP],&m->elementos[FilP][j]);
    Div = Fraccion_Dividir(&Mul,&Pivote);
    NuevoValor=Fraccion_Restar(&ValorAntiguo,&Div);
    
    return NuevoValor;
}

Fraccion TC_NuevoElementoFilP(Matriz *m,int i, int j, int FilP, int ColP){

    Fraccion Pivote = m->elementos[FilP][ColP];
    Fraccion Dividendo = m->elementos[i][j];
    Fraccion NuevoValor;
    NuevoValor = Fraccion_Dividir(&Dividendo,&Pivote);
    
    return NuevoValor;
}

Fraccion TC_NuevoElementoColP(Matriz *m,int i, int j, int FilP, int ColP){

    Fraccion Pivote = m->elementos[FilP][ColP];
    Fraccion Dividendo = m->elementos[i][j];
    Fraccion MenosUno;
    Fraccion NuevoValor;
    
    Fraccion_setValue(&MenosUno,-1,1);
    Dividendo = Fraccion_Multiplicar(&Dividendo,&MenosUno);
    
    NuevoValor = Fraccion_Dividir(&Dividendo,&Pivote);
    
    return NuevoValor;
}

Fraccion TC_NuevoPivote(Matriz *m,int FilP, int ColP){
    
    Fraccion Pivote = m->elementos[FilP][ColP];
    Fraccion Uno;
    Fraccion NuevoValor;
    Fraccion_setValue(&Uno,1,1);

    NuevoValor = Fraccion_Dividir(&Uno,&Pivote);
    return NuevoValor;


}